package com.JL.engine.model;

import com.JL.engine.GameWorld;
import com.JL.engine.components.DimensionComponent;
import com.JL.engine.components.PositionComponent;
import com.JL.engine.components.ViewComponent;

import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

public class Entity extends Component implements java.io.Serializable {
    // 组件容器，用来存放扩展组件

    private ConcurrentLinkedQueue<Component> components = new ConcurrentLinkedQueue<>();

    private  final PositionComponent positionComponent;

    private  final DimensionComponent dimensionComponent;

    private final ViewComponent viewComponent;

    {
        positionComponent = new PositionComponent();
        dimensionComponent = new DimensionComponent();
        viewComponent = new ViewComponent();
        // 将组件加入到实体中（必须调用，否则组件无法获取到实体）
        addComponent(positionComponent);
        addComponent(dimensionComponent);
        addComponent(viewComponent);
    }

    private GameWorld gameWorld;

    public List<Component> getComponents(){
        return new ArrayList<>(components);
    }

    public <T extends Component> T getComponent(Class<T> clazz){
        if(this.components.contains(clazz)){
            for(Component component : this.components){
                if(component.getClass().equals(clazz)){
                    return  (T) component;
                }
            }
        }

        for(Component component : this.components){
            if(clazz.isAssignableFrom(component.getClass())){
                return  (T) component;
            }
        }
        return null;
    }

    public void setGameWorld(GameWorld gameWorld){
        this.gameWorld = gameWorld;
    }

    public GameWorld getGameWorld(){
        return gameWorld;
    }

    // 将当前实体从游戏世界中移除
    public void remove(){
        gameWorld.removeEntity(this);
    }

    // 添加组件到实体中
    public void  addComponent(Component component){
        components.add(component);
        // 将当前实体传递给组件
        component.setEntity(this);
    }

    @Override
    public void onAdded(){
        for(Component component : components){
            component.onAdded();
        }
    }

    @Override
    public void onRemoved(){
        for(Component component : components){
            component.onRemoved();
        }
    }

    @Override
    public void update(double tpf){
        for(Component component : components){
            component.update(tpf);
        }
    }

    public double getX(){
        return this.positionComponent.getX();
    }

    public double getY(){
        return this.positionComponent.getY();
    }

    public double getWidth(){
        return this.dimensionComponent.getWidth();
    }

    public double getHeight(){
        return this.dimensionComponent.getHeight();
    }

    public void setPosition(double x, double y){
        this.positionComponent.setPosition(x,y);
    }

    public void setPosition(Point2D point){
        this.positionComponent.setPosition(point);
    }

    public void setTranslation(double x, double y){
        this.positionComponent.setTranslation(x,y);
    }

    public void setTranslation(Point2D point2D){
        this.positionComponent.setTranslation(point2D);
    }

    public void setSize(int width, int height) {
        this.dimensionComponent.setSize(width, height);
    }

    public void setSize(Dimension size) {
        this.dimensionComponent.setSize(size);
    }

    public void addView(View view){
        this.viewComponent.addView(view);
    }

    /*检测指定的坐标，是否在当前实体所表示的区域内
    *
    * */

    public boolean contains(Point2D point2D){
        // 构建当前实体所表示的区域矩形
        Rectangle2D rectangle2D = new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
        // 检测坐标点是否在当前矩形区域内
        return rectangle2D.contains(point2D);
    }



}
